package com.semidata.rtd.core.job;

import java.util.concurrent.Future;

import com.semidata.rtd.core.executor.TaskCompleteHandler;
import com.semidata.rtd.core.executor.TaskExecutor;

public abstract class ScheduledTask<T, C extends JobContext> implements Task<T>{
    
    private Job<C> job;
    private Future<T> future;
    private TaskExecutor executor;
    private boolean isCancelled;
    
    public ScheduledTask(Job<C> job, TaskExecutor executor) {
        this.job = job;
        this.executor = executor;
        this.future = null;
        this.isCancelled = false;
    }

    @Override
    public synchronized void submit() {
        if (isCancelled)
            return;
        future = executor.submit(this, new TaskCompleteHandler<T>() {

            @Override
            public void handle(Task<T> task, T result, Throwable cause) {
                
                try {
                    done(result, cause);
                } catch (Exception e) { 
                    cause = e;
                }
                if (result instanceof TaskResult) {
                	TaskResult tr = (TaskResult)result;
                	if (tr.getStatus().equals(Status.CONTINUE)) {
                		job.getTaskScheduler().schedule();
                	} else if (tr.getStatus().equals(Status.IGNORE)) {
                		System.out.println("");
                	} else {
                		job.getTaskScheduler().setError(cause);
                	}
                } else {
                	if (cause == null)
                		job.getTaskScheduler().schedule();
                	else 
                		job.getTaskScheduler().setError(cause);
                }
            }
        });
    }
    
    @Override
    public synchronized void cancel() {
        isCancelled = true;
        if (future != null)
            future.cancel(true);
    }
    
    protected Job<C> getJob() {
        return job;
    }
    
    protected abstract void done(T result, Throwable cause) throws Exception;

}
